package com.zimmur.service.impl.order;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.zimmur.dao.order.IWxPayLogDao;
import com.zimmur.model.account.CouponDetail;
import com.zimmur.model.account.PrepaidLog;
import com.zimmur.model.goods.GoodsOrganization;
import com.zimmur.model.order.Order;
import com.zimmur.model.order.OrderDetail;
import com.zimmur.model.order.WxPayLog;
import com.zimmur.service.account.ICouponService;
import com.zimmur.service.account.IPrepaidLogService;
import com.zimmur.service.goods.IGoodsOrganizationService;
import com.zimmur.service.order.IOrderDetailService;
import com.zimmur.service.order.IOrderService;
import com.zimmur.service.order.IWxPayLogService;
import com.zimmur.tools.DateUtils;
import com.zimmur.tools.PreciseCompute;

@Service("wxPayLogService")
public class WxPayLogServiceImpl implements IWxPayLogService {
	private static Logger log=LoggerFactory.getLogger(WxPayLogServiceImpl.class);
	
	@Resource
	private IWxPayLogDao wxPayLogDao;
	
	@Resource
	private IOrderService orderService;
	@Resource
	private IPrepaidLogService prepaidLogService;
	@Resource
	private IOrderDetailService orderDetailService;
	@Resource
	private IGoodsOrganizationService goodsOrganizationService;
	@Resource
	private ICouponService couponService;
	
	private static Object syncLock = new Object();
	@Override
	public boolean insertLog(WxPayLog log) {
		log.setResultCode("");
		return wxPayLogDao.insertSelective(log)>0?true:false;
	}

	@Transactional(propagation=Propagation.REQUIRES_NEW,rollbackFor={RuntimeException.class,Exception.class})
	public boolean updateNotifyPayStatus(String resultCode,String errCode,String errCodeDes,String openId,String isSubscribe,
			String outTradeNo, int notifydate,String bankType, int totalFee,int cashFee,String cashFeeType, int couponFee, int couponCount, 
			String transactionId, String timeEnd) {
		boolean bRet = false;
		try{
			WxPayLog notifyPay = wxPayLogDao.selectByOrderNo(outTradeNo);
			if(notifyPay != null && notifyPay.getIsFinish()==0){
				notifyPay.setNotifyDate(notifydate);
				notifyPay.setResultCode(resultCode);
				notifyPay.setErrCode(errCode);
				notifyPay.setErrCodeDes(errCodeDes);
				notifyPay.setOpenid(openId);
				notifyPay.setIsSubscribe(isSubscribe);
				notifyPay.setOutTradeNo(outTradeNo);
				
				notifyPay.setBankType(bankType);
				notifyPay.setTotalFee(totalFee);
				notifyPay.setCashFee(cashFee);
				notifyPay.setCashFeeType(cashFeeType);
				notifyPay.setCouponFee(couponFee);
				notifyPay.setCouponCount(couponCount);
				notifyPay.setTransactionId(transactionId);
				notifyPay.setTimeEnd(timeEnd);
				notifyPay.setIsFinish((short) 1);
				
				boolean bProcess=true;
				boolean isUsedCoupon=false;
				long orderId=0L;
				int payType = 1;////1=订单支付 2=充值支付
				if(resultCode.equals("SUCCESS") && notifyPay.getTotalFee() == totalFee){
					orderId = Long.parseLong(outTradeNo);
					Order order = orderService.selectByOrderId(orderId);
					if (order != null && order.getOderStatus().equals("00")) {
						bProcess = false;
						Short isusedCoupon = order.getIsusedCoupon();
						if (isusedCoupon != null && isusedCoupon == 1) {
							isUsedCoupon = true;
						}
					}
						
					if(!bProcess){
						double payJe = PreciseCompute.round(totalFee / 100.0, 2);
						if(payType == 1){											
							orderService.updateOrderStatusByPayNotify(Long.parseLong(outTradeNo), "wxpay",
									transactionId, payJe, "10", "已付款");							
						}
						if(payType == 2){
							prepaidLogService.updateStatus(outTradeNo, payJe, DateUtils.getNowUnixTime(),"wxpay",outTradeNo);
						}
						
						if(isUsedCoupon ){
							try {
								List<CouponDetail> couponDetails=couponService.selectCouponByOrderId(orderId);
								if (couponDetails!=null) {
									for(CouponDetail couponDetail:couponDetails){
										couponDetail.setCouponState("8");
										couponService.updateCoupon(couponDetail);
										couponService.updateCouponStock(couponDetail.getCouponStockId(), 1, 0, -1);
									}
								}
							} catch (Exception e) {
								log.error(e.getMessage(),e);
							}
						}
						
					}
					
				}
				
				bRet = wxPayLogDao.updatePayStatus(notifyPay)>0?true:false;
			}
		}catch(Exception er){
			bRet = false;
			log.error("updateNotifyPayStatus错误:"+er.getMessage(),er);
			throw new RuntimeException(er.getMessage());
		}
		
		return bRet;
	}

}
